package top.healthylife.gateway.platform.fh.api.api;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiModel;
import lombok.experimental.Accessors;
import top.healthylife.basics.utils.exception.BusinessException;
import top.healthylife.gateway.platform.fh.dto.unify.req.FhReqDetailsQueryUnifyDto;
import top.healthylife.gateway.platform.fh.dto.unify.req.FhReqQueryUnifyDto;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : GaoZeXi
 * @date 2021/11/9 10:41
 */

@Accessors(chain = true)
@ApiModel("法海出参统一处理接口")
public interface IUnifyHandler {

    String DATA_TYPE = "dataType";
    String ALL_LIST = "allList";
    String ENTRY_LIST = "entryList";
    String FDAPARTY_LIST = "fdapartyList";
    String COMPANY_GQCZ_LIST = "company_gqczList";
    String SUFFIX_LIST = "List";
    String SUFFIX_COUNT = "Count";
    String TOTAL_COUNT = "totalCount";
    String SUFFIX_PAGE_NUM = "PageNum";
    String CODE = "code";
    String MSG = "msg";
    String PAGE_NO = "pageNo";
    String RANGE = "range";

    /**
     * 根据数据类型填充子对象
     *
     * @param jsonObject 父对象
     * @param t          入参
     * @param clz        出参class
     * @return 出参
     */
    default <T> T fillFieldsByDataType(JSONObject jsonObject, FhReqQueryUnifyDto t, Class<T> clz) {
        Map<String, Object> map = BeanUtil.beanToMap(t);
        if (!map.containsKey(DATA_TYPE)) {
            throw new BusinessException("缺少关键参数dataType");
        }
        String dataType = String.valueOf(map.get(DATA_TYPE));
        JSONObject result = new JSONObject();
        //非详情查询
        String resList = dataType;
        if (!(t instanceof FhReqDetailsQueryUnifyDto)) {
            resList = dataType + SUFFIX_LIST;
        }
        JSONArray jsonArray = jsonObject.getJSONArray(resList);
        List<JSONObject> collect = jsonArray.stream().map(e -> (JSONObject) e).collect(Collectors.toList());
        collect.forEach(e -> modifyChildFieldByType(jsonObject, t, e, dataType));
        result.put(resList, collect);
        result.put(CODE, jsonObject.getString(CODE));
        result.put(MSG, jsonObject.getString(MSG));
        result.put(PAGE_NO, t.getPageno());
        result.put(RANGE, t.getRange());
        return result.toJavaObject(clz);
    }

    /**
     * 当 dataType 不传
     *
     * @param jsonObject 三方返回的对象
     * @param t          入参对象
     * @param clz        出参class
     * @return 出参
     */
    default <T> T fillAllFields(JSONObject jsonObject, FhReqQueryUnifyDto t, Class<T> clz) {
        JSONArray jsonArray;
        if (jsonObject.containsKey(ALL_LIST)) {
            jsonArray = jsonObject.getJSONArray(ALL_LIST);
        } else if (jsonObject.containsKey(ENTRY_LIST)) {
            jsonArray = jsonObject.getJSONArray(ENTRY_LIST);
        } else if (jsonObject.containsKey(FDAPARTY_LIST)) {
            jsonArray = jsonObject.getJSONArray(FDAPARTY_LIST);
        } else if (jsonObject.containsKey(COMPANY_GQCZ_LIST)) {
            jsonArray = jsonObject.getJSONArray(COMPANY_GQCZ_LIST);
        } else {
            throw new BusinessException("未知的返回列表");
        }
        JSONObject resObject = new JSONObject();
        List<JSONObject> collect = jsonArray.stream().map(e -> {
            if (!(e instanceof JSONObject)) {
                throw new BusinessException("数据结构异常,子节点不是JSONObject类型");
            }
            return (JSONObject) e;
        }).collect(Collectors.toList());
        Map<String, List<JSONObject>> map = collect.stream().collect(Collectors.groupingBy(e -> e.getString(DATA_TYPE)));
        map.forEach((k, v) -> {
            v.forEach(e -> modifyChildFieldByType(jsonObject, t, e, e.getString(DATA_TYPE)));
            resObject.put(k + SUFFIX_LIST, v);
        });

        resObject.put(CODE, jsonObject.getString(CODE));
        resObject.put(MSG, jsonObject.getString(MSG));
        resObject.put(PAGE_NO, t.getPageno());
        resObject.put(RANGE, t.getRange());
        return resObject.toJavaObject(clz);
    }


    /**
     * 为子对象添加属性
     *
     * @param parent   父对象
     * @param t        入参对象 用于判断当前接口类型,做兼容处理
     * @param child    子对象
     * @param dataType 数据类型
     */
    default void modifyChildFieldByType(JSONObject parent, FhReqQueryUnifyDto t, JSONObject child, String dataType) {
        //非详情查询
        String countStr = dataType + SUFFIX_COUNT;
        String pageNumStr = dataType + SUFFIX_PAGE_NUM;
        if (!(t instanceof FhReqDetailsQueryUnifyDto)) {
            child.put(countStr, parent.getInteger(countStr));
            child.put(pageNumStr, parent.getInteger(pageNumStr));
        } else {
            child.put(countStr, parent.getInteger(TOTAL_COUNT));
        }
    }
}
